#!/usr/bin/env bash

include "test.sh"

_Stack_nextid=1
function Stack::New()
{
    local symbol="$1"; shift
    eval '(( '$symbol' = _Stack_nextid++ ))'
    eval '__Stack_'${!symbol}'_index=0'
    eval '__Stack_'${!symbol}'_array=()'
}

function Stack::Del()
{
    local symbol="$1"; shift
    eval 'unset __Stack_'${!symbol}'_index'
    eval 'unset __Stack_'${!symbol}'_array'
}

function Stack::Push()
{
    local symbol="$1"; shift
    local value="$1"; shift
    eval '__Stack_'${!symbol}'_array[$__Stack_'${!symbol}'_index]="'$value'"'
    eval '((__Stack_'${!symbol}'_index++))'
}

function Stack::Pop()
{
    local symbol="$1"; shift
    if Stack::Empty "$symbol"; then
        assert_fail "stack is empty"
    fi

    eval '((__Stack_'${!symbol}'_index--))'
}

function Stack::Empty()
{
    local symbol="$1"; shift
    eval '((__Stack_'${!symbol}'_index == 0))'
}

function Stack::Top()
{
    local symbol="$1"; shift
    if Stack::Empty "$symbol"; then
        assert_fail "stack is empty"
    fi

    eval 'echo ${__Stack_'${!symbol}'_array[$((__Stack_'${!symbol}'_index-1))]}'
}

function Stack::Test1()
{
                              Stack::New stack
    test::should_return_true  Stack::Empty stack
                              Stack::Push stack asd
    test::should_return_false Stack::Empty stack
    test::run_cmd             Stack::Top stack
    test::should_be           asd
                              Stack::Push stack qwe
    test::run_cmd             Stack::Top stack
    test::should_be           qwe
                              Stack::Pop stack
    test::run_cmd             Stack::Top stack
    test::should_be           asd
                              Stack::Pop stack
                              Stack::Del stack
}
test::register_test Stack::Test1
